#include "Rational.h"


namespace Fractions
{
	Rational::Rational(int n, int d)
	{
		if (d<=0) 
			throw 	std::exception("denumerator can't be less than or equal to zero\n");
		num = n;
		denum = d;
	}

	
	void  Rational::set_num(int n)
	{
		num = n;
	}   
	
	void  Rational::set_denum(int d)
	{
		if (d <=0) 
			throw 	std::exception("denumerator can't be less than or equal to zero\n");
		denum = d;
	}
	
	
	
	void Rational::reduce()
	{
		int nod = NOD(num, denum);
		denum = denum/nod; num = num/nod;
	}
	
	
	int NOD(int a, int b)
	{
		a = std::abs(a);
		b = std::abs(b);
		if (b>a)
			std::swap(a,b);
		if (b==0) return a;
		return NOD (b, a%b);
	}


	std::ostream& operator << (std::ostream& outs, const Rational& r)
	{
		return outs << r.get_num() << '/' << r.get_denum(); 
	}

	std::istream& operator >> (std::istream& ins,  Rational& r)
	{
		int n,d;
		char c;

		ins >> n >> c >> d;
		if (!ins)
			return ins;
		if (c!='/')
		{
			ins.clear(std::ios_base::failbit);
			return ins;
		}
		r.set_num(n);
		r.set_denum(d);
		return ins;

	}


	Rational operator + (const Rational& r1, const Rational& r2)
	{
		int n  = r1.get_num()*r2.get_denum() + r2.get_num()*r1.get_denum();
		int d  = r1.get_denum()*r2.get_denum();
		return Rational(n,d);
	}
	Rational operator - (const Rational& r1, const Rational& r2)
	{
		int n  = r1.get_num()*r2.get_denum() - r2.get_num()*r1.get_denum();
		int d  = r1.get_denum()*r2.get_denum();
		return Rational(n,d);
	}
	
	Rational operator * (const Rational& r1, const Rational& r2)
	{
		int n  = r1.get_num()*r2.get_num();
		int d  = r1.get_denum()*r2.get_denum();
		return Rational(n,d);
	}
	
	
	Rational operator / (const Rational& r1, const Rational& r2)
	{
		
		if (r2.get_num() == 0) 
			throw  std::exception("Divide by zero");
		int n  = r1.get_num()*r2.get_denum();
		if (r2.get_num() < 0) n = -1*n;
		int d  = r1.get_denum()*abs(r2.get_num());
		return Rational(n,d);
	}

	Rational operator + (const Rational& r1, int r2)
	{
		int n  = r1.get_num() + r2*r1.get_denum();
		int d  = r1.get_denum();
		return Rational(n,d);
	
	}
	Rational operator - (const Rational& r1, int r2)
	{
		int n  = r1.get_num() - r2*r1.get_denum();
		int d  = r1.get_denum();
		return Rational(n,d);
	}
	Rational operator * (const Rational& r1, int r2)
	{
		int n  = r2*r1.get_num();
		int d  = r1.get_denum();
		return Rational(n,d);
	}
	Rational operator / (const Rational& r1, int r2)
	{
		if (r2 == 0) 
			throw  std::exception("Divide by zero");
		int n  = r1.get_num();
		if (r2 < 0) n = -1*n;
		int d  = r2*r1.get_denum();
		return Rational(n,d);
	}





}